<?php

namespace app\admin\model;

use GuzzleHttp\Client;
use think\db\exception\DbException;
use think\facade\Log;
use think\Model;
use think\model\relation\HasOne;

/**
 * OilOrder
 * @property mixed|string pay_price
 * @property int|mixed pay_time
 * @property int|mixed user_id
 * @property int|mixed transaction_id
 * @property int|mixed station_id
 * @property int|mixed oil_type
 * @property int|mixed gun_number
 * @property int|mixed coupon_id
 * @property int|mixed coupon_price
 * @property int|mixed oil_price
 * @property int|mixed order_sn
 * @property int|mixed total_price
 * @property int|mixed discount
 * @property int|mixed remark
 * @property int|mixed state
 * @property int|mixed commission
 * @property string datas
 * @property string|mixed pay_type
 * @property User user
 * @controllerUrl 'oilOrder'
 */
class OilOrder extends Model
{
    // 表名
    protected $name = 'oil_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $dateFormat = 'Y-m-d H:i:s';

    protected $type = [
        'pay_time' => 'timestamp:Y-m-d H:i:s',
        'delete_time' => 'timestamp:Y-m-d H:i:s',
    ];
    protected array $oilStateList = [
        0 => '待支付',
        1 => '已支付',
        2 => '退款中',
        3 => '已退款',
    ];


    public function getUserIdAttr($value, $row)
    {
        return !$value ? '' : $value;
    }

    public function getStationIdAttr($value, $row)
    {
        return !$value ? '' : $value;
    }

    /**
     * 获取唯一订单号
     * @return string
     * @throws DbException
     */
    public function getOrderSn(): string
    {
        try {
            [$micro, $time] = explode(' ', microtime());
            $micro = explode('.', sprintf('%.6f', $micro));
            $micro = $micro[1];
        } catch (\Exception $e) {
            $micro = rand(100000, 999999);
        }
        $orderSn = date('YmdHis') . $micro . rand(1000, 9999);
        $hasSn = $this->where('order_sn', $orderSn)->count();
        if ($hasSn > 0) {
            return $this->getOrderSn();
        }
        return $orderSn;
    }

    public function user(): HasOne
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }

    public function station(): HasOne
    {
        return $this->hasOne(Station::class, 'id', 'station_id');
    }

    public function paySuccess($message): bool
    {
        try {
            $order = $this->with(['user', 'station'])->where('order_sn', $message['out_trade_no'])->find();
            if (!$order) {
                Log::error($message['out_trade_no'] . '不存在');
                return false;
            }
            if ($order->pay_time > 0) {
                Log::error($message['out_trade_no'] . '已支付');
                return false;
            }
            if (isset($message['sign'])) unset($message['sign']);
            $order->datas = json_encode($message, JSON_UNESCAPED_UNICODE);
            $this->startTrans();
            // 订单设为已支付
            $order->pay_time = time();
            $order->state = 1;
            $order->transaction_id = $message['transaction_id'];
            // 用户支付次数和支付金额
            if (!$order->user) {
                Log::error('用户' . $order->user_id . '不存在');
                return false;
            }
            $order->user->pay_count += 1;
            $order->user->pay_money += $order->pay_price;
            // 开始分成
            $parentTree = $order->user->getParentTree($order->user->pid);
            $commission = [];
            $moneyLog = new UserMoneyLog();
            $commissionList = [
                get_sys_config('commission1'),
                get_sys_config('commission2'),
                get_sys_config('commission3'),
            ];
            foreach ($parentTree as $k => $parent) {

                if (strstr($commissionList[$k], '%')) {
                    $commissionList[$k] = sprintf('%.2f', str_replace('%', '', $commissionList[$k])) / 100;
                    $price = (float)bcmul($commissionList[$k], $order->pay_price, 2);
                } else {
                    $commissionList[$k] = floatval($commissionList[$k]);
                    $price = $commissionList[$k];
                }

                $commission[] = ["上级用户:{$parent->id};分佣比例:{$commissionList[$k]};加油金额:{$order->pay_price};获得佣金:{$price};"];
                $moneyLog->create([
                    'user_id' => $parent->id,
                    'money' => $price,
                    'memo' => "加油{$order->pay_price}元",
                ]);
                $parent->save();
            }
            $order->commission = json_encode($commission, JSON_UNESCAPED_UNICODE);
            $order->save();
            $order->user->upgrade($order->user->id);
            $this->commit();

            // 发送通知
            try {
                $wechat = new Wechat();

                $token = $wechat->getAccessToken();
                $appid = get_sys_config('wechat_appid'); // 公众号appid
                $openid = $order->user->routine_openid; // 用户小程序openid
                $template_id = get_sys_config('template_id'); // 公众号模板消息id
                $mini = [
                   // 'appid' => get_sys_config('routine_app_id'), // 小程序appid
                   // 'pagepath' => '/pages/store_map/orderdetail?id=', // 小程序路径
                ];

                $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=' . $token['access_token'];

                $params = [
                    'touser' => $openid,//小程序openid
                    'mp_template_msg' => [
                        'appid' => $appid,//公众号appid
                        'template_id' => $template_id,
                        'miniprogram' => $mini,
                        'data' => [
                            'first' => ['value' => '您好，本次加油已完成：', 'color' => '#000'],
                            'keyword1' => ['value' => $order->pay_price . '元', 'color' => '#000'],
                            'keyword2' => ['value' => $order->gun_number . '号枪' . $order->oil_type, 'color' => '#000'],
                            'keyword3' => ['value' => $order->station->station_name, 'color' => '#000'],
                            'keyword4' => ['value' => bcadd($order->discount, $order->coupon_price, 2) . '元', 'color' => '#000'],
                            'remark' => ['value' => '请出示给油站管理员查看', 'color' => '#f00'],
                        ],
                    ],
                ];

                $http = new Client;
                $res = $http->post($url, ['json' => $params])->getBody()->getContents();
                Log::error('模板消息发送结果：' . $res);
            } catch (\Exception $e) {
            }
            return true;
        } catch (\Exception $e) {
            Log::error($e->getFile() . ':' . $e->getLine() . '=>' . $e->getMessage());
            Log::error($e->getTraceAsString());
            echo $e->getFile() . ':' . $e->getLine() . '=>' . $e->getMessage() . PHP_EOL;
            echo $e->getTraceAsString();
            return false;
        }
    }

    public function getOilStateTxt($state)
    {
        return $this->oilStateList[$state] ?? '未知';
    }

    public function refund(): HasOne
    {
        return $this->hasOne(OilOrderRefund::class, 'order_id', 'id')->hidden([
            'createtime', 'updatetime', 'delete_time',
        ]);
    }
}